home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / mint / utils / gdb36p4s.zoo / cplus-dem.c < prev    next >
C/C++ Source or Header  |  1990-06-29  |  19KB  |  986 lines

  1. /* Demangler for GNU C++ 
  2.    Copyright (C) 1989 Free Software Foundation, Inc.
  3.    written by James Clark (jjc@jclark.uucp)
  4.    
  5.    This program is free software; you can redistribute it and/or modify
  6.    it under the terms of the GNU General Public License as published by
  7.    the Free Software Foundation; either version 1, or (at your option)
  8.    any later version.
  9.  
  10.    This program is distributed in the hope that it will be useful,
  11.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.    GNU General Public License for more details.
  14.  
  15.    You should have received a copy of the GNU General Public License
  16.    along with this program; if not, write to the Free Software
  17.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. /* This is for g++ 1.36.1 (November 6 version). It will probably
  20.    require changes for any other version.
  21.  
  22.    Modified for g++ 1.36.2 (November 18 version).  */
  23.  
  24. /* This file exports one function
  25.  
  26.    char *cplus_demangle (const char *name, int ansi)
  27.    
  28.    If NAME is a mangled function name produced by GNU C++, then
  29.    a pointer to a malloced string giving a C++ representation
  30.    of the name will be returned; otherwise NULL will be returned.
  31.    It is the caller's responsibility to free the string which
  32.    is returned.
  33.  
  34.    If ANSI is non-zero, then ANSI qualifiers such as `const',
  35.    `void', and the ellipses operator `...' are output.  Otherwise
  36.    they are not.
  37.  
  38.    For example,
  39.    
  40.    cplus_demangle ("_foo__1Ai")
  41.    
  42.    returns
  43.  
  44.    "A::foo(int)"
  45.  
  46.    This file imports xmalloc and xrealloc, which are like malloc and
  47.    realloc except that they generate a fatal error if there is no
  48.    available memory. */
  49.  
  50. /* #define nounderscore 1 /* define this is names don't start with _ */
  51.  
  52. #include <stdio.h>
  53. #include <ctype.h>
  54.  
  55. #ifdef USG
  56. #include <memory.h>
  57. #include <string.h>
  58. #else
  59. #include <strings.h>
  60. #define memcpy(s1, s2, n) bcopy ((s2), (s1), (n))
  61. #define memcmp(s1, s2, n) bcmp ((s2), (s1), (n))
  62. #define strchr index 
  63. #define strrchr rindex
  64. #endif
  65.  
  66. #ifndef __STDC__
  67. #define const
  68. #endif
  69.  
  70. #ifdef __STDC__
  71. extern char *cplus_demangle (const char *type, int ansi);
  72. #else
  73. extern char *cplus_demangle ();
  74. #endif
  75.  
  76. #ifdef __STDC__
  77. extern char *xmalloc (int);
  78. extern char *xrealloc (char *, int);
  79. #else
  80. extern char *xmalloc ();
  81. extern char *xrealloc ();
  82. #endif
  83.  
  84. static char **typevec = 0;
  85. static int ntypes = 0;
  86. static int typevec_size = 0;
  87.  
  88. static struct {
  89.   const char *in;
  90.   const char *out;
  91. } optable[] = {
  92.   "new", " new",
  93.   "delete", " delete",
  94.   "ne", "!=",
  95.   "eq", "==",
  96.   "ge", ">=",
  97.   "gt", ">",
  98.   "le", "<=",
  99.   "lt", "<",
  100.   "plus", "+",
  101.   "minus", "-",
  102.   "mult", "*",
  103.   "convert", "+",    /* unary + */
  104.   "negate", "-",    /* unary - */
  105.   "trunc_mod", "%",
  106.   "trunc_div", "/",
  107.   "truth_andif", "&&",
  108.   "truth_orif", "||",
  109.   "truth_not", "!",
  110.   "postincrement", "++",
  111.   "postdecrement", "--",
  112.   "bit_ior", "|",
  113.   "bit_xor", "^",
  114.   "bit_and", "&",
  115.   "bit_not", "~",
  116.   "call", "()",
  117.   "cond", "?:",
  118.   "alshift", "<<",
  119.   "arshift", ">>",
  120.   "component", "->",
  121.   "indirect", "*",
  122.   "method_call", "->()",
  123.   "addr", "&",        /* unary & */
  124.   "array", "[]",
  125.   "nop", "",            /* for operator= */
  126. };
  127.  
  128. /* Beware: these aren't '\0' terminated. */
  129.  
  130. typedef struct {
  131.   char *b;            /* pointer to start of string */
  132.   char *p;            /* pointer after last character */
  133.   char *e;            /* pointer after end of allocated space */
  134. } string;
  135.  
  136. #ifdef __STDC__
  137. static void string_need (string *s, int n);
  138. static void string_delete (string *s);
  139. static void string_init (string *s);
  140. static void string_clear (string *s);
  141. static int string_empty (string *s);
  142. static void string_append (string *p, const char *s);
  143. static void string_appends (string *p, string *s);
  144. static void string_appendn (string *p, const char *s, int n);
  145. static void string_prepend (string *p, const char *s);
  146. #if 0
  147. static void string_prepends (string *p, string *s);
  148. #endif
  149. static void string_prependn (string *p, const char *s, int n);
  150. static int get_count (const char **type, int *count);
  151. static int do_args (const char **type, string *decl);
  152. static int do_type (const char **type, string *result);
  153. static int do_arg (const char **type, string *result);
  154. static int do_args (const char **type, string *decl);
  155. static void munge_function_name (string *name);
  156. static void remember_type (const char *type, int len);
  157. #else
  158. static void string_need ();
  159. static void string_delete ();
  160. static void string_init ();
  161. static void string_clear ();
  162. static int string_empty ();
  163. static void string_append ();
  164. static void string_appends ();
  165. static void string_appendn ();
  166. static void string_prepend ();
  167. static void string_prepends ();
  168. static void string_prependn ();
  169. static int get_count ();
  170. static int do_args ();
  171. static int do_type ();
  172. static int do_arg ();
  173. static int do_args ();
  174. static void munge_function_name ();
  175. static void remember_type ();
  176. #endif
  177.  
  178. static int print_ansi_qualifiers;
  179.  
  180. char *
  181. cplus_demangle (type, ansi)
  182.      const char *type;
  183.      int ansi;
  184. {
  185.   string decl;
  186.   int n;
  187.   int success = 0;
  188.   int constructor = 0;
  189.   int const_flag = 0;
  190.   int i;
  191.   const char *p;
  192. #ifndef LONGERNAMES
  193.   const char *premangle;
  194. #endif
  195.  
  196.   print_ansi_qualifiers = ansi;
  197.  
  198.   if (type == NULL || *type == '\0')
  199.     return NULL;
  200. #ifndef nounderscore
  201.   if (*type++ != '_')
  202.     return NULL;
  203. #endif
  204.   p = type;
  205.   while (*p != '\0' && !(*p == '_' && p[1] == '_'))
  206.     p++;
  207.   if (*p == '\0')
  208.     {
  209.       /* destructor */
  210.       if (type[0] == '_' && type[1] == '$' && type[2] == '_')
  211.     {
  212.       int n = (strlen (type) - 3)*2 + 3 + 2 + 1;
  213.       char *tem = (char *) xmalloc (n);
  214.       strcpy (tem, type + 3);
  215.       strcat (tem, "::~");
  216.       strcat (tem, type + 3);
  217.       strcat (tem, "()");
  218.       return tem;
  219.     }
  220.       /* static data member */
  221.       if (*type != '_' && (p = strchr (type, '$')) != NULL)
  222.     {
  223.       int n = strlen (type) + 2;
  224.       char *tem = (char *) xmalloc (n);
  225.       memcpy (tem, type, p - type);
  226.       strcpy (tem + (p - type), "::");
  227.       strcpy (tem + (p - type) + 2, p + 1);
  228.       return tem;
  229.     }
  230.       /* virtual table */
  231.       if (type[0] == '_' && type[1] == 'v' && type[2] == 't' && type[3] == '$')
  232.     {
  233.       int n = strlen (type + 4) + 14 + 1;
  234.       char *tem = (char *) xmalloc (n);
  235.       strcpy (tem, type + 4);
  236.       strcat (tem, " virtual table");
  237.       return tem;
  238.     }
  239.       return NULL;
  240.     }
  241.  
  242.   string_init (&decl);
  243.  
  244.   if (p == type)
  245.     {
  246.       if (!isdigit (p[2]))
  247.     {
  248.       string_delete (&decl);
  249.       return NULL;
  250.     }
  251.       constructor = 1;
  252.     }
  253.   else
  254.     {
  255.       string_appendn (&decl, type, p - type);
  256.       munge_function_name (&decl);
  257.     }
  258.   p += 2;
  259.  
  260. #ifndef LONGERNAMES
  261.   premangle = p;
  262. #endif
  263.   switch (*p)
  264.     {
  265.     case 'C':
  266.       /* a const member function */
  267.       if (!isdigit (p[1]))
  268.     {
  269.       string_delete (&decl);
  270.       return NULL;
  271.     }
  272.       p += 1;
  273.       const_flag = 1;
  274.       /* fall through */
  275.     case '0':
  276.     case '1':
  277.     case '2':
  278.     case '3':
  279.     case '4':
  280.     case '5':
  281.     case '6':
  282.     case '7':
  283.     case '8':
  284.     case '9':
  285.       n = 0;
  286.       do
  287.     {
  288.       n *= 10;
  289.       n += *p - '0';
  290.       p += 1;
  291.     }
  292.       while (isdigit (*p));
  293.       if (strlen (p) < n)
  294.     {
  295.       string_delete (&decl);
  296.       return NULL;
  297.     }
  298.       if (constructor)
  299.     {
  300.       string_appendn (&decl, p, n);
  301.       string_append (&decl, "::");
  302.       string_appendn (&decl, p, n);
  303.     }
  304.       else
  305.     {
  306.       string_prepend (&decl, "::");
  307.       string_prependn (&decl, p, n);
  308.     }
  309.       p += n;
  310. #ifndef LONGERNAMES
  311.       remember_type (premangle, p - premangle);
  312. #endif
  313.       success = do_args (&p, &decl);
  314.       if (const_flag)
  315.     string_append (&decl, " const");
  316.       break;
  317.     case 'F':
  318.       p += 1;
  319.       success = do_args (&p, &decl);
  320.       break;
  321.     }
  322.  
  323.   for (i = 0; i < ntypes; i++)
  324.     if (typevec[i] != NULL)
  325.       free (typevec[i]);
  326.   ntypes = 0;
  327.   if (typevec != NULL)
  328.     {
  329.       free ((char *)typevec);
  330.       typevec = NULL;
  331.       typevec_size = 0;
  332.     }
  333.  
  334.   if (success)
  335.     {
  336.       string_appendn (&decl, "", 1);
  337.       return decl.b;
  338.     }
  339.   else
  340.     {
  341.       string_delete (&decl);
  342.       return NULL;
  343.     }
  344. }
  345.  
  346. static int
  347. get_count (type, count)
  348.      const char **type;
  349.      int *count;
  350. {
  351.   if (!isdigit (**type))
  352.     return 0;
  353.   *count = **type - '0';
  354.   *type += 1;
  355.   /* see flush_repeats in cplus-method.c */
  356.   if (isdigit (**type))
  357.